<template>
    <div>
        <div class="btn-list">
            <el-button type="primary" @click="clickCamera"
                >开启摄像头</el-button
            >
            <el-button @click="clickVideo">启用本地视频</el-button>
        </div>
        <div class="video-box" @mousemove="handleMouseMove">
            <video
                ref="videoRef"
                :src="testVideo"
                @canplay="handleCanPlay"
                @timeupdate="handleTimeUpdate"
                @ended="handleVideoEnded"
            ></video>
            <div class="control-box" :class="controlShow ? 'control-show' : ''">
                <div class="control">
                    <div
                        class="rewind-box"
                        @click="clickRewind"
                        v-if="isLocalVideo"
                    >
                        <svg
                            t="1719278343879"
                            class="icon"
                            viewBox="0 0 1024 1024"
                            version="1.1"
                            xmlns="http://www.w3.org/2000/svg"
                            p-id="3154"
                            width="32"
                            height="32"
                        >
                            <path
                                d="M800 866.912l-512-352 512-352zM288 157.088v704H224v-704z"
                                fill="#bfbfbf"
                                p-id="3155"
                            ></path>
                        </svg>
                    </div>
                    <div class="play-pause-box" @click="togglePlayStatus">
                        <div v-if="isPlaying">
                            <svg
                                t="1719216609581"
                                class="icon"
                                viewBox="0 0 1030 1024"
                                version="1.1"
                                xmlns="http://www.w3.org/2000/svg"
                                p-id="11056"
                                width="32"
                                height="32"
                            >
                                <path
                                    d="M511.999996 0C229.260123 0-4.0e-06 229.238701-4.0e-06 512c0 282.782725 229.238701 512 512 512 282.782725 0 512-229.217275 512-512C1024.021422 229.238701 794.804147 0 511.999996 0zM511.999996 958.842986c-246.786743 0-446.82156-200.056244-446.82156-446.842986 0-246.786743 200.056244-446.82156 446.82156-446.82156 246.829595 0 446.842986 200.034818 446.842986 446.82156C958.864408 758.786743 758.829591 958.842986 511.999996 958.842986z"
                                    p-id="11057"
                                    fill="#bfbfbf"
                                ></path>
                                <path
                                    d="M365.102105 328.52762l85.70472 0 0 385.671242-85.70472 0 0-385.671242Z"
                                    p-id="11058"
                                    fill="#bfbfbf"
                                ></path>
                                <path
                                    d="M536.511546 328.52762l107.130901 0 0 385.671242-107.130901 0 0-385.671242Z"
                                    p-id="11059"
                                    fill="#bfbfbf"
                                ></path>
                            </svg>
                        </div>
                        <div v-else>
                            <svg
                                t="1719216538627"
                                class="icon"
                                viewBox="0 0 1024 1024"
                                version="1.1"
                                xmlns="http://www.w3.org/2000/svg"
                                p-id="10836"
                                width="32"
                                height="32"
                            >
                                <path
                                    d="M772.7 217.7a32.2 32.1 0 1 0 64.4 0 32.2 32.1 0 1 0-64.4 0Z"
                                    fill="#bfbfbf"
                                    p-id="10837"
                                ></path>
                                <path
                                    d="M415.8 679.9c5.9 0 11.5-1.6 16.2-4.5l231.1-134.6c10.9-5.2 18.5-16.3 18.5-29.2 0-11.9-6.4-22.3-16-27.8L439.7 352.2c-5.8-6.7-14.4-10.9-23.9-10.9-17.6 0-31.8 14.4-31.8 32.1 0 0.6 0 1.2 0.1 1.8l-0.4 0.2 0.5 269c-0.1 1.1-0.2 2.2-0.2 3.4 0 17.7 14.3 32.1 31.8 32.1z"
                                    fill="#bfbfbf"
                                    p-id="10838"
                                ></path>
                                <path
                                    d="M909.8 306.6c-5.4-10.5-16.3-17.8-28.9-17.8-17.8 0-32.2 14.4-32.2 32.1 0 6 1.7 11.7 4.6 16.5l-0.1 0.1c26.9 52.4 42.1 111.8 42.1 174.7 0 211.6-171.6 383.2-383.2 383.2S128.8 723.8 128.8 512.2 300.4 129.1 512 129.1c62.5 0 121.5 15 173.6 41.5l0.2-0.4c4.6 2.6 10 4.1 15.7 4.1 17.8 0 32.2-14.4 32.2-32.1 0-13.1-7.9-24.4-19.3-29.4C653.6 81.9 584.9 64.5 512 64.5 264.7 64.5 64.3 265 64.3 512.2S264.7 959.9 512 959.9s447.7-200.4 447.7-447.7c0-74.1-18-144-49.9-205.6z"
                                    fill="#bfbfbf"
                                    p-id="10839"
                                ></path>
                            </svg>
                        </div>
                    </div>
                    <div
                        class="forward-box"
                        @click="clickForward"
                        v-if="isLocalVideo"
                    >
                        <svg
                            t="1719278296213"
                            class="icon"
                            viewBox="0 0 1024 1024"
                            version="1.1"
                            xmlns="http://www.w3.org/2000/svg"
                            p-id="11845"
                            width="32"
                            height="32"
                        >
                            <path
                                d="M224 866.912l512-352-512-352zM736 157.088v704h64v-704z"
                                fill="#bfbfbf"
                                p-id="11846"
                            ></path>
                        </svg>
                    </div>
                    <div class="process">
                        <el-slider
                            v-model="percentage"
                            @change="handleProgressChange"
                            :format-tooltip="formatTooltip"
                        />
                        <div class="duration-box">
                            <span class="current-time">{{
                                videoCurrentTime
                            }}</span>
                            <span class="duration" v-if="isLocalVideo">{{
                                formatTotal
                            }}</span>
                        </div>
                    </div>
                    <div class="voice" @click="toggleVoiceStatus">
                        <div v-if="isMute">
                            <svg
                                t="1719218103498"
                                class="icon"
                                viewBox="0 0 1024 1024"
                                version="1.1"
                                xmlns="http://www.w3.org/2000/svg"
                                p-id="12321"
                                width="32"
                                height="32"
                            >
                                <path
                                    d="M448 938.666667a21.333333 21.333333 0 0 1-15.093333-6.246667L225.833333 725.333333H53.333333a53.393333 53.393333 0 0 1-53.333333-53.333333V352a53.393333 53.393333 0 0 1 53.333333-53.333333h172.5l207.08-207.086667A21.333333 21.333333 0 0 1 469.333333 106.666667v810.666666a21.333333 21.333333 0 0 1-21.333333 21.333334zM53.333333 341.333333a10.666667 10.666667 0 0 0-10.666666 10.666667v320a10.666667 10.666667 0 0 0 10.666666 10.666667h181.333334a21.333333 21.333333 0 0 1 15.086666 6.246666L426.666667 865.833333V158.166667L249.753333 335.086667A21.333333 21.333333 0 0 1 234.666667 341.333333z m964.42 377.753334a21.333333 21.333333 0 0 0 0-30.173334L840.833333 512l176.92-176.913333a21.333333 21.333333 0 1 0-30.173333-30.173334L810.666667 481.833333 633.753333 304.913333a21.333333 21.333333 0 0 0-30.173333 30.173334L780.5 512l-176.92 176.913333a21.333333 21.333333 0 0 0 30.173333 30.173334L810.666667 542.166667l176.913333 176.92a21.333333 21.333333 0 0 0 30.173333 0z"
                                    fill="#bfbfbf"
                                    p-id="12322"
                                ></path>
                            </svg>
                        </div>
                        <div v-else>
                            <svg
                                t="1719218051228"
                                class="icon"
                                viewBox="0 0 1024 1024"
                                version="1.1"
                                xmlns="http://www.w3.org/2000/svg"
                                p-id="12107"
                                width="32"
                                height="32"
                            >
                                <path
                                    d="M128 420.576v200.864h149.12l175.456 140.064V284.288l-169.792 136.288H128z m132.256-64l204.288-163.968a32 32 0 0 1 52.032 24.96v610.432a32 32 0 0 1-51.968 24.992l-209.92-167.552H96a32 32 0 0 1-32-32v-264.864a32 32 0 0 1 32-32h164.256zM670.784 720.128a32 32 0 0 1-44.832-45.664 214.08 214.08 0 0 0 64.32-153.312 213.92 213.92 0 0 0-55.776-144.448 32 32 0 1 1 47.36-43.04 277.92 277.92 0 0 1 72.416 187.488 278.08 278.08 0 0 1-83.488 198.976zM822.912 858.88a32 32 0 1 1-45.888-44.608A419.008 419.008 0 0 0 896 521.152c0-108.704-41.376-210.848-114.432-288.384a32 32 0 0 1 46.592-43.872c84.16 89.28 131.84 207.04 131.84 332.256 0 127.84-49.76 247.904-137.088 337.728z"
                                    fill="#bfbfbf"
                                    p-id="12108"
                                ></path>
                            </svg>
                        </div>
                    </div>
                    <div class="speed" v-if="isLocalVideo">
                        <el-dropdown placement="top">
                            <span class="speed-text">{{ currentSpeed }}</span>
                            <template #dropdown>
                                <el-dropdown-menu>
                                    <el-dropdown-item
                                        :class="{
                                            'active-drop-item':
                                                item === currentSpeed,
                                        }"
                                        v-for="item in speedList"
                                        :key="item"
                                        @click="clickChangeSpeed(item)"
                                        >{{ item }}</el-dropdown-item
                                    >
                                </el-dropdown-menu>
                            </template>
                        </el-dropdown>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script lang="ts" setup>
import { ref } from "vue";
import testVideo from "@/assets/testVideo1.mp4";
const totalDuration = ref(0);
const videoRef = ref();
const percentage = ref(0);
const isPlaying = ref(false);
const isMute = ref(true);
const formatTotal = ref("");
const videoCurrentTime = ref("00:00:00");
const speedList = ref(["0.5", "1.0", "1.5"]);
const currentSpeed = ref("1.0");
const controlShow = ref(true);
const timer = ref();
const mediaStreamTrack = ref(null);
const isLocalVideo = ref(true);
// 视频加载完毕
const handleCanPlay = () => {
    totalDuration.value = videoRef.value.duration;
    formatTotal.value = handleFormatTime(totalDuration.value);
    handleMouseMove();
};
const handleFormatTime = (time) => {
    let formatCount = "";
    if (time < 60) {
        formatCount = `00:00:` + parseInt(time).toString().padStart(2, "0");
    } else if (time < 3600) {
        formatCount =
            `00:` +
            parseInt(time / 60)
                .toString()
                .padStart(2, "0") +
            `:` +
            parseInt(time % 60)
                .toString()
                .padStart(2, "0");
    } else {
        formatCount =
            parseInt(time / 3600)
                .toString()
                .padStart(2, "0") +
            `:` +
            parseInt((time % 3600) / 60)
                .toString()
                .padStart(2, "0") +
            `:` +
            parseInt(time % 60)
                .toString()
                .padStart(2, "0");
    }
    return formatCount;
};
// 播放时间改变
const handleTimeUpdate = () => {
    const currentTime = videoRef.value.currentTime;
    videoCurrentTime.value = handleFormatTime(currentTime);
    const p = Math.ceil((currentTime / videoRef.value.duration) * 100);
    percentage.value = p;
};
// 快退
const clickRewind = () => {
    const time = videoRef.value.currentTime - 5;
    videoRef.value.currentTime = time < 0 ? 0 : time;
};
// 快进
const clickForward = () => {
    const time = videoRef.value.currentTime + 5;
    const duration = videoRef.value.duration;
    videoRef.value.currentTime = time > duration ? duration : time;
};
// 播放/暂停
const togglePlayStatus = () => {
    isPlaying.value = !isPlaying.value;
    videoRef.value.paused ? videoRef.value.play() : videoRef.value.pause();
};
// 静音/取消静音
const toggleVoiceStatus = () => {
    isMute.value = !isMute.value;
    videoRef.value.muted = isMute.value;
};
// 进度条控制
const handleProgressChange = (val: number) => {
    videoRef.value.currentTime = (val / 100) * totalDuration.value;
};
// 视频播放结束
const handleVideoEnded = () => {
    isPlaying.value = false;
    percentage.value = 0;
    videoRef.value.pause();
    videoRef.value.currentTime = 0;
};
// 格式化进度条提示
const formatTooltip = () => {
    if (isLocalVideo.value) {
        const p = (percentage.value / 100) * totalDuration.value;
        return handleFormatTime(p);
    } else {
        return videoCurrentTime.value;
    }
};
// 修改播放速度
const clickChangeSpeed = (item) => {
    videoRef.value.playbackRate = item;
    currentSpeed.value = item;
};
// 鼠标移入显示控制条
const handleMouseMove = () => {
    if (!controlShow.value) {
        controlShow.value = true;
    }
    if (timer.value) {
        clearTimeout(timer.value);
    }
    timer.value = setTimeout(() => {
        controlShow.value = false;
    }, 3000);
};
// 开启摄像头
const clickCamera = () => {
    isLocalVideo.value = false;
    isPlaying.value = true;
    navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(
        (stream) => {
            // mediaStreamTrack = stream.getTracks()[0];
            mediaStreamTrack.value = stream;
            videoRef.value.srcObject = stream;
            videoRef.value?.play();
        },
        (err) => {
            console.error(err);
        }
    );
};
// 关闭摄像头
const clickCloseCamera = () => {
    if (mediaStreamTrack.value) {
        mediaStreamTrack.value.getVideoTracks().forEach((track) => {
            track.stop();
        });
        mediaStreamTrack.value.getAudioTracks().forEach((track) => {
            track.stop();
        });
        videoRef.value.srcObject = null;
        videoRef.value.pause();
    }
};
const clickVideo = () => {
    isLocalVideo.value = true;
    isPlaying.value = false;
    clickCloseCamera();
    videoRef.value.src = testVideo;
};
</script>

<style lang="scss" scoped>
.btn-list {
    margin-bottom: 10px;
}
.video-box {
    position: relative;
    width: 800px;
    height: 450px;
    color: #fff;
    video {
        width: 100%;
        height: 100%;
        background-color: #000;
    }
    .control-box {
        display: none;
    }
    .control-show {
        display: block;
    }
    .control {
        width: 100%;
        height: 50px;
        padding: 0 10px;
        box-sizing: border-box;
        bottom: 0;
        position: absolute;
        background-color: rgba(0, 0, 0, 0.7);
        display: flex;
        align-items: center;
        .rewind-box,
        .play-pause-box,
        .forward-box,
        .voice {
            &:hover {
                cursor: pointer;
            }
        }
        .play-pause-box {
            margin: 0 10px;
        }
        svg {
            width: 26px;
            height: 26px;
        }
        .process {
            position: relative;
            flex: 1;
            margin: 0 15px;
            .duration-box {
                width: 100%;
                top: 20px;
                position: absolute;
                display: flex;
                justify-content: space-between;
            }
        }
        .speed {
            margin: 0 10px;
            .speed-text {
                font-size: 16px;
                color: #fff;
                &:focus-visible {
                    outline: none;
                }
            }
        }
        :deep(.el-slider__button) {
            width: 15px;
            height: 15px;
        }
    }
}
</style>
<style lang="scss">
.active-drop-item {
    color: #00aeec;
}
</style>
